package kingone.phone_store_spring_practice.service.impl;

import kingone.phone_store_spring_practice.entity.PhoneCategory;
import kingone.phone_store_spring_practice.entity.PhoneInfo;
import kingone.phone_store_spring_practice.entity.PhoneSpecs;
import kingone.phone_store_spring_practice.enums.ResultEnum;
import kingone.phone_store_spring_practice.exception.PhoneException;
import kingone.phone_store_spring_practice.repository.PhoneCategoryRepository;
import kingone.phone_store_spring_practice.repository.PhoneInfoRepository;
import kingone.phone_store_spring_practice.repository.PhoneSpecsRepository;
import kingone.phone_store_spring_practice.service.PhoneService;
import kingone.phone_store_spring_practice.util.PhoneUtil;
import kingone.phone_store_spring_practice.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/*此处的作用：写出代码，实现将对应的底层数据查找以后，封装进接口中*/
@Service
@Slf4j
public class PhoneServiceImpl implements PhoneService {

    @Autowired
    private PhoneCategoryRepository phoneCategoryRepository;
    @Autowired
    private PhoneInfoRepository phoneInfoRepository;
    @Autowired
    private PhoneSpecsRepository phoneSpecsRepository;


    @Override
    public DataVO findDataVO() {
        DataVO dataVO = new DataVO();
//1.将类型的信息进行封装
        List<PhoneCategory> phoneCategoryList = phoneCategoryRepository.findAll();

//        //取出phoneCategoryList的部分属性值，加入到接口封装类中
//        List<PhoneCategoryVO> phoneCategoryVOList = new ArrayList<>();  //此处与上面的phoneCategoryList是对应的
//        for (PhoneCategory phoneCategory : phoneCategoryList) {
//            /*将phoneCategory中取出的信息封装进每一个PhoneCategoryVO后，然后将入到集合中*/
//            PhoneCategoryVO phoneCategoryVO = new PhoneCategoryVO();
//            phoneCategoryVO.setCategoryName(phoneCategory.getCategoryName());
//            phoneCategoryVO.setCategoryType(phoneCategory.getCategoryType());
//
//            phoneCategoryVOList.add(phoneCategoryVO);
//        }
//        dataVO.setCategories(phoneCategoryVOList);

        /*使用jdk8的新特性-流的方式进行数据对接*/
        List<PhoneCategoryVO> phoneCategoryVOList = phoneCategoryList.stream()
                .map(e -> new PhoneCategoryVO(
                        e.getCategoryName(),
                        e.getCategoryType()
                )).collect(Collectors.toList());

        dataVO.setCategories(phoneCategoryVOList);

//2.将某类型手机的具体信息进行封装
        //此处完成根据上面获取到的phoneCategory集合中第一位的类型，进行查找该类型手机的具体信息
        List<PhoneInfo> phoneInfoList = phoneInfoRepository.findAllByCategoryType(phoneCategoryList.get(0).getCategoryType());

//        List<PhoneInfoVO> phoneInfoVOList = new ArrayList<>();
//        for (PhoneInfo phoneInfo : phoneInfoList) {
//            PhoneInfoVO phoneInfoVO = new PhoneInfoVO();
//            /*注意此处使用BeanUtils中的方法，实现将相同名字的属性拷贝过去*/
//            BeanUtils.copyProperties(phoneInfo,phoneInfoVO);
//
//            //对于tag需要进行特殊处理
//            phoneInfoVO.setTag(PhoneUtil.createTag(phoneInfo.getPhoneTag()));
//
//            phoneInfoVOList.add(phoneInfoVO);
//        }
//        dataVO.setPhones(phoneInfoVOList);

        List<PhoneInfoVO> phoneInfoVOList = phoneInfoList.stream()
                .map(e ->new PhoneInfoVO(
                        e.getPhoneId(),
                        e.getPhoneName(),
                        e.getPhonePrice()+".00",  //此处是为了统一转成字符串类型
                        e.getPhoneDescription(),
                        PhoneUtil.createTag(e.getPhoneTag()),
                        e.getPhoneIcon()
                )).collect(Collectors.toList());
        dataVO.setPhones(phoneInfoVOList);

        return dataVO;
    }

    @Override
    public List<PhoneInfoVO> findPhoneInfoVOByCategoryType(Integer categoryType) {
        List<PhoneInfo> phoneInfoList = phoneInfoRepository.findAllByCategoryType(categoryType);

        List<PhoneInfoVO> phoneInfoVOList = phoneInfoList.stream().map(e -> new PhoneInfoVO(
                e.getPhoneId(),
                e.getPhoneName(),
                e.getPhonePrice() + ".00",  //此处是为了统一转成字符串类型
                e.getPhoneDescription(),
                PhoneUtil.createTag(e.getPhoneTag()),
                e.getPhoneIcon()
        )).collect(Collectors.toList());

        return phoneInfoVOList;
    }

    @Override
    public SpecsPackageVO findSpecsPackageVOByPhoneId(Integer phoneId) {
        /*由于此处涉及到手机的详细信息、规格信息，所以需要先将其获得，再进行处理*/
        PhoneInfo phoneInfo = phoneInfoRepository.findById(phoneId).get();
        List<PhoneSpecs> phoneSpecsList = phoneSpecsRepository.findAllByPhoneId(phoneId);

        /*数据封装顺序：goods + sku(tree(k + v(对应的PhoneSpecsVO) + k_s) + list(对应的PhoneSpecsCasVO) +其他);
        * 且从下到大进行封装*/
//1.封装tree和list
        ArrayList<PhoneSpecsVO> phoneSpecsVOList = new ArrayList<>();
        ArrayList<PhoneSpecsCasVO> phoneSpecsCasVOList = new ArrayList<>();
        PhoneSpecsVO phoneSpecsVO;
        PhoneSpecsCasVO phoneSpecsCasVO;

            //将相应信息放入对应集合中
        for (PhoneSpecs phoneSpecs : phoneSpecsList) {
            phoneSpecsVO = new PhoneSpecsVO();
            phoneSpecsCasVO = new PhoneSpecsCasVO();

            BeanUtils.copyProperties(phoneSpecs,phoneSpecsVO);
            BeanUtils.copyProperties(phoneSpecs,phoneSpecsCasVO);

            phoneSpecsVOList.add(phoneSpecsVO);
            phoneSpecsCasVOList.add(phoneSpecsCasVO);
        }
            //将tree中的信息进行封装，并成集合
        TreeVO treeVO = new TreeVO();
        treeVO.setV(phoneSpecsVOList);
        ArrayList<TreeVO> treeVOList = new ArrayList<>();
        treeVOList.add(treeVO);

//2.封装sku
        SkuVO skuVO = new SkuVO();
        //解决price的类型问题：从BigDecimal→int→String
        int price = phoneInfo.getPhonePrice().intValue();
        skuVO.setPrice(price+".00");
        skuVO.setStock_num(phoneInfo.getPhoneStock());
        skuVO.setTree(treeVOList);
        skuVO.setList(phoneSpecsCasVOList);

//3.封装最外层的data:含有goods+sku
        SpecsPackageVO specsPackageVO = new SpecsPackageVO();

        Map<String, String> goods = new HashMap<>();
        goods.put("picture",phoneInfo.getPhoneIcon());

        specsPackageVO.setSku(skuVO);
        specsPackageVO.setGoods(goods);

        return specsPackageVO;
    }

    @Override
    public void subStock(Integer specsId, Integer quantity) {
        /*注意库存情况是：所有型号(32G+64G)手机的库存总和；因此在修改库存时，需要同时修改型号库存、总库存*/
        PhoneSpecs phoneSpecs = phoneSpecsRepository.findById(specsId).get();
        PhoneInfo phoneInfo = phoneInfoRepository.findById(phoneSpecs.getPhoneId()).get();

        int result = phoneSpecs.getSpecsStock()-quantity;
        if(result < 0){
            log.error("【扣库存】时，库存不足！");
            //抛出异常，并将相关异常传递给前端
            throw new PhoneException(ResultEnum.PHONE_STOCK_ERROR);
        }

        phoneSpecs.setSpecsStock(result);
        phoneSpecsRepository.save(phoneSpecs);

        result = phoneInfo.getPhoneStock() - quantity;
        if(result < 0){
            log.error("【扣库存】时，库存不足！");
            //抛出异常，并将相关异常传递给前端
            throw new PhoneException(ResultEnum.PHONE_STOCK_ERROR);
        }
        phoneInfo.setPhoneStock(result);
        phoneInfoRepository.save(phoneInfo);
    }


}
